﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UCodeFirstConfig.cs" company="CodePlex">
//   The MIT License
//   Copyright (c) 2013 Julien Blin
//   
//   Permission is hereby granted, free of charge, to any person obtaining a copy
//   of this software and associated documentation files (the "Software"), to deal
//   in the Software without restriction, including without limitation the rights
//   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//   copies of the Software, and to permit persons to whom the Software is
//   furnished to do so, subject to the following conditions:
//   
//   The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//   
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//   THE SOFTWARE.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace UCodeFirst
{
    using System;
    using System.Configuration;
    using System.IO;
    using System.Linq;

    using umbraco.BusinessLogic;

    using Umbraco.Core;
    using Umbraco.Core.Logging;

    /// <summary>
    /// Allows the retrieval of uCodeFirst configuration values.
    /// </summary>
    public static class UCodeFirstConfig
    {
        /// <summary>
        /// Default username if nothing specified.
        /// </summary>
        private const string DefaultUsername = @"uCodeFirst";

        /// <summary>
        /// Configuration key for the username.
        /// </summary>
        private const string ConfigurationKeyUsername = @"uCodeFirstUser";

        /// <summary>
        /// Configuration key for the synchronization mode.
        /// </summary>
        private const string ConfigurationKeySynchronizationMode = @"uCodeFirstSynchronizationMode";

        /// <summary>
        /// The uCodeFirst user.
        /// </summary>
        private static User user;

        /// <summary>
        /// Gets the synchronization mode.
        /// </summary>
        public static SynchronizationMode SynchronizationMode
        {
            get
            {
                var configValue = ConfigurationManager.AppSettings[ConfigurationKeySynchronizationMode];
                if (string.IsNullOrEmpty(configValue))
                {
                    return SynchronizationMode.Auto;
                }

                return (SynchronizationMode)Enum.Parse(typeof(SynchronizationMode), configValue);
            }
        }

        /// <summary>
        /// Gets the uCodeFirst <see cref="User"/>.
        /// </summary>
        /// <exception cref="UCodeFirstException">
        /// If no user is specified, or too many users with the same name, or the admin UserType and the user don't exists.
        /// </exception>
        /// <returns>
        /// The <see cref="User"/>.
        /// </returns>
        public static User GetUser()
        {
            if (user == null)
            {
                var username = ConfigurationManager.AppSettings[ConfigurationKeyUsername];
                if (string.IsNullOrEmpty(username))
                {
                    username = DefaultUsername;
                }

                var umbUsers = User.GetAllByLoginName(username, false).ToList();
                if (umbUsers.Count() == 1)
                {
                    user = umbUsers.First();
                }

                if (umbUsers.Count() > 1)
                {
                    throw new UCodeFirstException(Resources.TooManyUsers.InvariantFormat(username, ConfigurationKeyUsername));
                }

                if (!umbUsers.Any())
                {
                    var adminUserType = UserType.GetAllUserTypes().FirstOrDefault(x => x.Alias.Equals("admin", StringComparison.InvariantCultureIgnoreCase));
                    if (adminUserType == null)
                    {
                        throw new UCodeFirstException(Resources.UnableToFindAdminUserType.InvariantFormat(username, ConfigurationKeyUsername));
                    }

                    user = User.MakeNew(username, username, Path.GetRandomFileName(), adminUserType);
                    user.disable();
                    user.LoginName = username;
                    user.NoConsole = true;
                    user.Save();
                    LogHelper.Info(typeof(UCodeFirstConfig), Resources.CreatedUser.InvariantFormat(username));
                }
            }

            return user;
        }
    }
}
